package com.techsen.tsweb.sys.security;

import java.util.List;

import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import com.techsen.tsweb.core.util.SubjectUtil;
import com.techsen.tsweb.core.util.ValidUtil;
import com.techsen.tsweb.sys.domain.Acl;
import com.techsen.tsweb.sys.domain.User;
import com.techsen.tsweb.sys.domain.UserRole;
import com.techsen.tsweb.sys.service.AclService;
import com.techsen.tsweb.sys.service.UserRoleService;
import com.techsen.tsweb.sys.service.UserService;
import com.techsen.tsweb.sys.util.SysConst;

@Component("localRealm")
public class LocalRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;
    
    @Resource
    private UserRoleService userRoleService;
    
    @Resource
    private AclService aclService;
    
    /**
     * 收集授权信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo();
        if (!principals.isEmpty()) {
            User user = (User) SubjectUtil.getSubject().getSession().getAttribute(SysConst.LOGIN_USER);
            
            /**
             * 根据用户查找用户的角色
             */
            List<String> roleIds = UserRole.getRoleIdsByUserRoles(
                    this.userRoleService.getListByEntity(new UserRole().setUserId(user.getId())));
            if (ValidUtil.isValid(roleIds)) {
                sai.addRoles(roleIds);
            }
            
            /**
             * 查找直接授权给用户的权限
             */
            List<Acl> acls = this.aclService.getListByEntity(new Acl()
                    .setPrincipalType(User.class.getSimpleName().toLowerCase())
                    .setPrincipalId(user.getId()));
            if (ValidUtil.isValid(acls)) {
                for (Acl acl : acls) {
                    sai.addObjectPermission(acl.getAclPermission());
                }
            }
            
        }
        return sai;
    }

    /**
     * 收集认证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        if (token instanceof UsernamePasswordToken) {
            UsernamePasswordToken upt = (UsernamePasswordToken) token;
            String username = upt.getUsername();
            String password = String.valueOf(upt.getPassword());
            
            User user = this.userService.getOneByEntity(new User().setLoginAct(username).setLoginPwd(password));
            SubjectUtil.getSubject().getSession().setAttribute(SysConst.LOGIN_USER, user);
            
            if (user != null) {
                return new SimpleAuthenticationInfo(username, password, this.getName());
            } else {
                throw new UnknownAccountException("用户名和密码不正确");
            }
        }
        return null;
    }

}
